package com.zxz.aop;

import com.zxz.vo.JsonResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.SpelCompilerMode;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
@Aspect
public class TestAspect {
    @Around("@annotation(anno)")
    public Object around(ProceedingJoinPoint point, TestAspectAnno anno) throws Throwable {
        System.out.println("around start");
        try {
            return point.proceed();
        }catch (Exception e){
            System.out.println("around Exception");
            throw e;
        }finally {
            System.out.println("around end");
        }
    }

    @After("@annotation(anno)")
    public void after(JoinPoint point,TestAspectAnno anno){
        System.out.println("after args:"+point.getArgs());
    }

    @AfterReturning(returning = "json",pointcut = "@annotation(anno)")
    public JsonResult afterReturning(JsonResult json, TestAspectAnno anno) throws Throwable {
        System.out.println("TestAspect start");
        Object response = json.getResponse();
        if(response != null){
            System.out.println("TestAspect response is not null");
        }
        System.out.println("TestAspect end");
        return json;
    }

    @AfterThrowing(pointcut = "@annotation(anno)")
    public void afterThrowing(JoinPoint point,TestAspectAnno anno){
        System.out.println("AfterThrowing args"+point.getArgs()[0]);
        ExpressionParser expressionParser =new SpelExpressionParser();
        EvaluationContext ctx = new StandardEvaluationContext();
        //在上下文中设置变量，变量名为user，内容为user对象
        ctx.setVariable("args", point.getArgs());
        Object value = expressionParser.parseExpression(anno.name()).getValue(ctx);
        System.out.println("TestAspect afterThrowing start");
        System.out.println("TestAspectAnno name is "+value.toString());
        System.out.println("TestAspect afterThrowing");
    }
}
